#include <climits>
#include "fixed_pack.hpp"
#include "fixed_helper.hpp"
#include "topcvt_policyhelper.hpp"
#include "topcvt_policycontext.hpp"

namespace topcvt
{
     void FixedPack::checkElementCfgValid(AttributeableCfg& t)
    {
        if (t.getCfgType() == cfgtype_t::E_POLICY )
        {
            check(t);
        }
        else if (t.getCfgType() == cfgtype_t::E_FIELD)
        {
            string fldval = t.get("len");
            int sLen = topcvt_string::to_int<string>(fldval);
            PolicyHelper::checkIntRange(t, "len", -1, INT_MAX);
            PolicyHelper::checkIntRange(t, "offset", -1, INT_MAX);
            check(t);
        }
    }  

    void FixedPack::check(AttributeableCfg& t)
    {
        PolicyHelper::checkValidRange(t, "fillType", { "byte", "char" });
        PolicyHelper::checkValidRange(t, "fillLocation", { "left", "right" });
    }

    void FixedPack::packField(pugi::xml_node& node, FieldCfg& f, PolicyContext& ctx)
    {
        string value("");
        string variant = f.getName();
        string sLen = f.get("len");

        value = PolicyContext::getFldVal(ctx,variant);
        value = PolicyHelper::getPackFieldValue(ctx, f, value, m_atx);

        int len = topcvt_string::to_int<string>(sLen);

        TLOG_TRACE("field:name=%s len=%d", variant.c_str(), len);

        if (len > 0)
        {
            string sOffset = f.get("offset");
            int offset = topcvt_string::to_int<string>(sOffset);
            if (offset != -1) 
            {
                string fillType = ctx.getNodeAttr(f, "fillType", "char");
                string fillLocation = ctx.getNodeAttr(f, "fillLocation", DEFAULT_FILL_LOCATION);
                bool left = true;
                if (fillLocation == "right")
                    left = false;
                char ch = 0;
                if (fillType == "char")
                {
                    string fillChar = ctx.getNodeAttr(f, "fillChar", " ");
                    ch = fillChar[0];
                }
                else if (fillType == "byte") 
                {
                    string fillChar = ctx.getNodeAttr(f, "fillChar", "0");
                    ch = topcvt_string::to_int<string>(fillChar);
                }
                if (left)
                    topcvt_string::fillchar_left(value,len,ch);
                else
                    topcvt_string::fillchar_right(value,len, ch);
            }
        }
        TLOG_DEBUG("field:%s-->[%d][%s]",variant.c_str(),len,value.c_str());
        m_message.put(value);
    }

};